# coding=utf-8

from flask import render_template, flash, redirect, url_for, session, Markup
from flask_login import login_user, logout_user, current_user

from app.routes.auth import bp
from app.routes.auth.forms import LoginForm, RegistrationForm, ResetForm, ResetPasswordForm, EmailAuthenticationForm
from app.models import User
from app.routes.auth.email import send_email_reset_password, send_email_authentication
from app.utils.util import redirect_back


@bp.route('/login', methods=['GET', 'POST'])
def login():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = LoginForm()
    if form.validate_on_submit():
        username = form.username.data
        user = User.query.filter_by(username=username).first()
        if user and user.check_password(passowrd=form.password.data):
            login_user(user=user, remember=True)
            flash("{} 登录成功".format(user.username))
            return redirect_back()
        else:
            flash("用户不存在或密码错误", category="warning")
            return redirect(url_for("auth.login"))
    return render_template("auth/login.html", title="登录", form=form)


@bp.route("/logout")
def logout():
    if current_user.is_anonymous:
        flash('当前没有用户登录', category="error")
    logout_user()
    return redirect(url_for("main.index"))


@bp.route("/email_authentication", methods=['GET', 'POST'])
def email_authentication():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = EmailAuthenticationForm()
    if form.validate_on_submit():
        email = form.email.data
        send_email_authentication(email=email)
        session['email_authentication'] = email
        message = Markup('已向邮箱 {} 发送认证邮件，请前往邮箱认证 '
                         '<br>'
                         '未收到？<a class="alert-link" href="{}">重新发送邮件</a>'.format(
            email,
            url_for('auth.resend_authentication', email=email),)
        )
        # flash("已向邮箱 {} 发送认证邮件，请前往邮箱认证".format(email))
        flash(message)
        return redirect(url_for("auth.email_authentication"))
    return render_template("auth/email_authentication.html", title="邮箱认证", form=form)


@bp.route("/register/<token>", methods=["GET", "POST"])
def register(token):
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = RegistrationForm()
    email_token = User.get_email_from_token(token=token)
    email_session = session.get('email_authentication', None)
    if email_token != email_session:
        flash("跳转链接中的邮箱地址{}与会话中记录的请求认证邮箱地址{}不一致，可能原因如下：\n"
              "1). 认证邮件已超时失效\n"
              "2). 发起认证的浏览器与当前使用的必须为同一浏览器".format(email_token, email_session), category="error")
        return redirect(url_for("auth.email_authentication"))
    form.email.data = email_token
    form.email.render_kw.update(dict(disabled="disabled"))
    if form.validate_on_submit():
        if User.check_existence_buy_username_email(username=form.username.data,
                                                   email=form.email.data):
            flash('用户{}和邮箱{}之前已经注册，可直接登录'.format(form.username.data, form.email.data))
            return redirect(url_for('auth.login'))
        User.add(username=form.username.data,
                 email=form.email.data,
                 password=form.password.data)
        flash('{} 用户注册成功'.format(form.username.data), category='success')
        return redirect(url_for('auth.login'))
    return render_template("auth/register.html", title="用户注册", form=form, token=token)


@bp.route('/resend_authentication/<email>', methods=['GET'])
def resend_authentication(email):
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    send_email_authentication(email=email)
    flash('已重新向邮箱 {} 发送认证邮件，请前往邮箱认证'.format(email))
    return redirect(url_for('auth.email_authentication'))


@bp.route('/reset_password', methods=['GET', 'POST'])
def reset_password():
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = ResetPasswordForm()
    if form.validate_on_submit():
        email = form.email.data
        session['email_reset_password'] = email
        send_email_reset_password(email=email)
        # flash("已向邮箱 {} 发送密码重置邮件，请前往邮箱确认".format(email))
        message = Markup('已向邮箱 {} 发送认证邮件，请前往邮箱认证 '
                         '<br>'
                         '未收到？<a class="alert-link" href="{}">重新发送邮件</a>'.format(
            email,
            url_for('auth.resend_reset_password', email=email), )
        )
        flash(message)
        return redirect(url_for('auth.login'))
    return render_template('auth/reset_password.html', title='密码重置', form=form)


@bp.route('/resend_reset_password/<email>', methods=['GET'])
def resend_reset_password(email):
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    send_email_reset_password(email=email)
    flash('已重新向邮箱 {} 发送重置邮件，请前往邮箱认证'.format(email))
    return redirect(url_for('auth.reset_password'))


@bp.route('/reset/<token>', methods=['GET', 'POST'])
def reset(token):
    if current_user.is_authenticated:
        return redirect(url_for('main.index'))
    form = ResetForm()
    email_token = User.get_email_from_token(token=token)
    email_session = session.get('email_reset_password', None)
    if email_token != email_session:
        flash("跳转链接中的邮箱地址{}与会话中记录的请求重置邮箱地址{}不一致，可能原因如下：\n"
              "1). 重置邮件已超时失效\n"
              "2). 发起密码重置的浏览器与当前使用的必须为同一浏览器".format(email_token, email_session), category="error")
        return redirect(url_for("auth.reset_password_request"))
    form.email.data = email_token
    form.email.render_kw.update(dict(disabled='disabled'))
    users = User.query.filter_by(email=email_token).all()
    choices = [(user.username, user.username) for user in users]
    form.usernames.choices = choices
    if form.validate_on_submit():
        email = form.email.data
        usernames = form.usernames.data
        password = form.password.data
        for username in usernames:
            User.update_password(username=username, email=email, password=password)
        flash('密码重置成功', category='success')
        return redirect(url_for('auth.login'))
    return render_template('/auth/reset.html', title='密码重置', form=form, token=token)
